package com.quad.innovators.salesease.listener;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.quad.innovators.salesease.common.base.BaseAnalysisEventListener;
import com.quad.innovators.salesease.common.utils.SmUtils;
import com.quad.innovators.salesease.common.utils.SystemCodeUtils;
import com.quad.innovators.salesease.constants.SecurityConstants;
import com.quad.innovators.salesease.converter.SysUserConverter;
import com.quad.innovators.salesease.enums.StatusEnum;
import com.quad.innovators.salesease.enums.SystemCodeEnum;
import com.quad.innovators.salesease.model.dto.SysUserImportDTO;
import com.quad.innovators.salesease.model.entity.SysRole;
import com.quad.innovators.salesease.model.entity.SysUser;
import com.quad.innovators.salesease.model.entity.SysUserRole;
import com.quad.innovators.salesease.service.SysRoleService;
import com.quad.innovators.salesease.service.SysUserRoleService;
import com.quad.innovators.salesease.service.SysUserService;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户导入监听器
 * <p>
 * <a href="https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read#%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84%E8%AF%BB%E7%9A%84%E7%9B%91%E5%90%AC%E5%99%A8">最简单的读的监听器</a>
 *
 * @author Ray
 * @since 2022/4/10
 */
@Slf4j
public class SysUserImportListener extends BaseAnalysisEventListener<SysUserImportDTO> {


    // 有效条数
    private int validCount;

    // 无效条数
    private int invalidCount;

    // 导入返回信息
    StringBuilder msg = new StringBuilder();

    private final SysUserService sysUserService;
    private final SysUserConverter sysUserConverter;
    private final SysRoleService sysRoleService;
    private final SysUserRoleService sysUserRoleService;

    public SysUserImportListener() {
        this.sysUserService = SpringUtil.getBean(SysUserService.class);
        this.sysRoleService = SpringUtil.getBean(SysRoleService.class);
        this.sysUserRoleService = SpringUtil.getBean(SysUserRoleService.class);
        this.sysUserConverter = SpringUtil.getBean(SysUserConverter.class);
    }

    /**
     * 每一条数据解析都会来调用
     * <p>
     * 1. 数据校验；全字段校验
     * 2. 数据持久化；
     *
     * @param userImportDTO 一行数据，类似于 {@link AnalysisContext#readRowHolder()}
     */
    @Override
    public void invoke(SysUserImportDTO userImportDTO, AnalysisContext analysisContext) {
        log.info("解析到一条用户数据:{}", JSONUtil.toJsonStr(userImportDTO));
        // 校验数据
        StringBuilder validationMsg = new StringBuilder();
        String username = userImportDTO.getUsername();
        if (StrUtil.isBlank(username)) {
            validationMsg.append("用户名为空；");
        } else {
            long count = sysUserService.count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
            if (count > 0) {
                validationMsg.append("用户名已存在；");
            }
        }

        String mobile = userImportDTO.getTelephone();
        if (StrUtil.isBlank(mobile)) {
            validationMsg.append("手机号码为空；");
        } else {
            if (!Validator.isMobile(mobile)) {
                validationMsg.append("手机号码不正确；");
            }
        }

        if (validationMsg.isEmpty()) {
            // 校验通过，持久化至数据库
            // 设置默认加密密码
            String defaultPassword = "Aa" + userImportDTO.getTelephone().substring(5);
            SysUser entity = sysUserConverter.toEntity(userImportDTO);
            entity.setUserCode(SystemCodeUtils.getCode(SystemCodeEnum.USER));
            entity.setPassword(SmUtils.sm4Encrypt(SmUtils.sm4Encrypt(SecurityConstants.FRONT_END_PASSWORD_ENCRYPT_KEY,defaultPassword)));   // 默认密码
            // 角色解析
            String roleCodes = userImportDTO.getRoleName();
            List<String> roleIds = null;
            if (StrUtil.isNotBlank(roleCodes)) {
                roleIds = sysRoleService.list(
                                new LambdaQueryWrapper<SysRole>()
                                        .in(SysRole::getName, (Object) roleCodes.split(","))
                                        .eq(SysRole::getStatus, StatusEnum.ENABLE.getValue())
                                        .select(SysRole::getCode)
                        ).stream()
                        .map(SysRole::getCode)
                        .collect(Collectors.toList());
            }
            boolean saveResult = sysUserService.save(entity);
            if (saveResult) {
                validCount++;
                // 保存用户角色关联
                if (CollectionUtil.isNotEmpty(roleIds)) {
                    List<SysUserRole> userRoles = roleIds.stream()
                            .map(roleId -> new SysUserRole(entity.getUserCode(), roleId))
                            .collect(Collectors.toList());
                    sysUserRoleService.saveBatch(userRoles);
                }
            } else {
                invalidCount++;
                msg.append("第").append(validCount + invalidCount).append("行数据保存失败；<br/>");
            }
        } else {
            invalidCount++;
            msg.append("第").append(validCount + invalidCount).append("行数据校验失败：").append(validationMsg + "<br/>");
        }
    }


    /**
     * 所有数据解析完成会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("所有数据解析完成！");

    }


    @Override
    public String getMsg() {
        // 总结信息
        return StrUtil.format("导入用户结束：成功{}条，失败{}条；<br/>{}", validCount, invalidCount, msg);
    }
}
